package com.feifan.web.controller.oa;

import com.feifan.common.annotation.Log;
import com.feifan.common.core.controller.BaseController;
import com.feifan.common.core.domain.AjaxResult;
import com.feifan.common.core.page.TableDataInfo;
import com.feifan.common.enums.BusinessType;
import com.feifan.common.utils.poi.ExcelUtil;
import com.feifan.framework.util.ShiroUtils;
import com.feifan.oa.domain.FlowCategoryInfo;
import com.feifan.oa.domain.Leave;
import com.feifan.oa.service.*;
import com.feifan.system.domain.SysUser;
import com.feifan.web.controller.utils.ApprovedUtil;
import com.feifan.web.controller.utils.LeaveUtil;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;

/**
 * 请假Controller
 * @author 非凡
 * @date 2020-07-04
 */
@Controller
@RequestMapping("/oa/leave")
public class LeaveController extends BaseController {
    private String prefix = "oa/sponsorFlow/leave";

    @Autowired
    private ILeaveService leaveService;

    @Autowired
    private IFlowCategoryDetailService flowCategoryDetailService;

    @Autowired
    private IFlowCategoryInfoService flowCategoryInfoService;

    @Autowired
    private ILeaveCheckService leaveCheckService;

    @Autowired
    private IHolidayWorkingDateService holidayWorkingDateService;

    /**
     * 获取请假天数
     */
    @RequestMapping("getLeaveDays")
    @ResponseBody
    public AjaxResult getLeaveDays(String id, String startTime, String endTime) throws ParseException {
        return LeaveUtil.caulateTotalTime2(Long.parseLong(id), startTime, endTime);
    }

    /**
     * 获取假期设置
     */
    @RequestMapping("getLeaveSetting")
    @ResponseBody
    public AjaxResult getLeaveSetting(String id, @RequestParam(defaultValue = "0") Integer days) {
        return AjaxResult.warn(LeaveUtil.verificationVacation(Long.parseLong(id), days));
    }

    /**
     * 获取一个日期的n天后
     * @param date 开始日期
     * @param days 天数
     * @return 日期
     * @throws ParseException
     */
    @PostMapping("/getSpecialTime")
    @ResponseBody
    public AjaxResult getSpecialTime(String date, Integer days) throws ParseException {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(formatter.parse(date));
        c.add(Calendar.DATE, days - 1);
        return AjaxResult.success(formatter.format(c.getTime()));
    }

    @RequiresPermissions("oa:leave:view")
    @GetMapping()
    public String leave(ModelMap mmap) {
        mmap.put("flowCategoryInfoList", flowCategoryInfoService.selectFlowCategoryInfoList(null));
        return prefix + "/leave";
    }

    /**
     * 查询请假列表
     */
    @RequiresPermissions("oa:leave:list")
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(Leave leave) {
        startPage();
        SysUser sysUser = new SysUser();
        leave.setSysUser(sysUser);
        sysUser.setUserId(ShiroUtils.getUserId());
        List<Leave> list = leaveService.selectLeaveList(leave);
        return getDataTable(list);
    }

    /**
     * 导出请假列表
     */
    @RequiresPermissions("oa:leave:export")
    @Log(title = "请假", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(Leave leave) {
        List<Leave> list = leaveService.selectLeaveList(leave);
        ExcelUtil<Leave> util = new ExcelUtil<Leave>(Leave.class);
        return util.exportExcel(list, "leave");
    }

    /**
     * 新增请假
     */
    @GetMapping("/add")
    public String add(ModelMap mmap) {
        mmap.put("holidayWorkingDate", holidayWorkingDateService.selectHolidayWorkingDateList());
        mmap.put("flowCategoryInfoList", flowCategoryInfoService.selectFlowCategoryInfoList(null));
        return prefix + "/add";
    }

    /**
     * 新增保存请假
     */
    @RequiresPermissions("oa:leave:add")
    @Log(title = "请假", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(Leave leave,
                              @RequestParam("leavePic") MultipartFile leavePic) throws ParseException, IOException {
        if (!StringUtils.isEmpty(leave.getId()) && leave.getStatus().equals(0)) {
            leaveService.deleteLeaveById(leave.getId());
        }

        //获取当前登录的用户
        SysUser sysUser = ShiroUtils.getSysUser();
        if (sysUser.getUserId() == 1) {
            return AjaxResult.warn("管理员无需请假!");
        }
        leave.setSysUser(sysUser);
        leave.setStatus(1);

        if (StringUtils.isEmpty(leave.getId())) {
            List<Leave> leaves = leaveService.selectLeaveList(leave);
            if (leaves.size() != 0) {
                return AjaxResult.error("当前您有请假流程未完成!");
            }
        }

        //请假天数
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Integer leaveDays = LeaveUtil.caulateTotalTime3(leave.getFlowCategoryInfo().getId(),
                format.format(leave.getBeginDate()), format.format(leave.getFinishDate()));
        if (leaveDays != null && leaveDays <= 0) {
            return AjaxResult.warn("0天无需请假");
        }
        leave.setLeaveDays(leaveDays);

        String leaveSetting = LeaveUtil.verificationVacation(leave.getFlowCategoryInfo().getId(),
                leave.getLeaveDays());
        if (!leaveSetting.equals(leave.getLeaveDays().toString())) {
            return AjaxResult.warn(leaveSetting);
        }


        //添加请假单
        leaveService.insertLeave(leave, leavePic);

        //获取流程分类id
        FlowCategoryInfo flowCategoryInfo =
                flowCategoryInfoService.selectFlowCategoryInfoById(leave.getFlowCategoryInfo().getId());

        //获取审批的层数
        int i = flowCategoryDetailService.selectFlowCategoryDetailTierCheck(flowCategoryInfo.getFlowCategory().getId(), leaveDays);

        //添加审批
        ApprovedUtil.approved(flowCategoryInfo, leave, i, sysUser.getDeptId(), sysUser.getUserId());

        return AjaxResult.success();
    }

    /**
     * 修改请假
     */
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Long id, ModelMap mmap) {
        mmap.put("flowCategoryInfoList", flowCategoryInfoService.selectFlowCategoryInfoList(null));
        mmap.put("leave", leaveService.selectLeaveById(id));
        return prefix + "/edit";
    }

    /**
     * 修改保存请假
     */
    @RequiresPermissions("oa:leave:edit")
    @Log(title = "请假", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(Leave leave) {
        return toAjax(leaveService.updateLeave(leave));
    }

    /**
     * 删除请假
     */
    @RequiresPermissions("oa:leave:remove")
    @Log(title = "请假", businessType = BusinessType.DELETE)
    @PostMapping("/remove")
    @ResponseBody
    public AjaxResult remove(String ids) {
        return toAjax(leaveService.deleteLeaveByIds(ids));
    }


    /**
     * 获取请假详情
     */
    @RequiresPermissions("oa:leave:detail")
    @Log(title = "请假", businessType = BusinessType.OTHER)
    @GetMapping("/leaveDetail/{id}")
    public String leaveDetail(@PathVariable("id") Long id, ModelMap mmap) {
        mmap.put("leave", leaveService.selectLeaveById(id));
        return prefix + "/detail";
    }

    /**
     * 查询请假单的审批记录
     * @param id 请假单id
     * @return 审批记录集合
     */
    @PostMapping("/leaveCheckDetail/{id}")
    @ResponseBody
    public TableDataInfo leaveCheckDetail(@PathVariable("id") Long id) {
        startPage();
        return getDataTable(leaveCheckService.selectLeaveCheckByLId(id));
    }

    /**
     * 获取驳回原因
     * @param id 审批id
     * @return 驳回原因
     */
    @PostMapping("/getRejectReason/{id}")
    @ResponseBody
    public AjaxResult getRejectReason(@PathVariable("id") Long id) {
        return AjaxResult.success(leaveCheckService.selectLeaveCheckById(id));
    }

}
